package cn.com.pumpkin.aop;

import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class IocContainer implements BeanFactory{
	
	private Map<String,Object> beanCantainer = new ConcurrentHashMap<String,Object>();
	
	private Map<String,Class<?>> beanDefine  = new ConcurrentHashMap<String,Class<?>>();
	
	private Aspect aspect ;
	
	public void setAspect(Aspect aspect){
		this.aspect = aspect;
	}
	
	public void addBeanDefine(String alias,Class<?> clazz){
		beanDefine.put(alias, clazz);
	}
	
	@SuppressWarnings("unchecked")
	private <T> T instance(Class<?> clazz) throws Exception{
		return (T) clazz.newInstance();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public <T> T getBean(String alias) throws Exception{
		T bean = (T) beanCantainer.get(alias);
		if(bean == null){
			bean = instance(beanDefine.get(alias));
			bean = EnhanceInstance(bean);
			beanCantainer.put(alias, bean);
		}
		return bean;
	}
	
	@SuppressWarnings("unchecked")
	private <T> T EnhanceInstance(T bean){
		//在类结构上检测是否需要增强
		if(aspect.pointCut.matchClassGateway(bean.getClass()))
			return (T)Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), new MiddlewareInvocationHandler(aspect,bean));
		return bean;
	}
 
}
